<template>
  <div class="canvas">
    <div class="btns">
      <a-button
        v-for="(item, index) in doList"
        :key="`btn-${index}`"
        @click="clickBtn(item)"
        >{{ item.label }}</a-button
      >
    </div>
    <canvas
      ref="canvasRef"
      class="my-canvas"
      width="1000"
      height="800"
      @mousedown="canvasMousedown"
      @mouseleave="canvasMouseleave"
      @mouseup="canvasMouseup"
    ></canvas>
  </div>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'

const canvasRef = ref<HTMLCanvasElement | null>(null)
const ctx = ref<CanvasRenderingContext2D | null>(null)
let current = -1
const doList = reactive([
  {
    show: false,
    x: 0,
    y: 0,
    label: '矩形边框',
    handler(x = doList[0].x, y = doList[0].y) {
      if (!ctx.value) return
      ctx.value.strokeStyle = '#ff0000'
      ctx.value.strokeRect(x, y, 100, 100)
    },
  },
  {
    show: false,
    x: 100,
    y: 0,
    label: '矩形填充',
    handler(x = doList[1].x, y = doList[1].y) {
      if (!ctx.value) return
      ctx.value.fillRect(x, y, 100, 100)
    },
  },
  {
    show: false,
    x: 200,
    y: 0,
    label: '圆圈',
    handler(x = doList[2].x, y = doList[2].y, r = 50) {
      if (!ctx.value) return
      ctx.value.arc(x + r, y + r, r, 0, 2 * Math.PI)
      ctx.value.stroke()
      //   ctx.value.fill()
    },
  },
])
onMounted(() => {
  if (canvasRef.value) {
    ctx.value = canvasRef.value.getContext('2d') as CanvasRenderingContext2D
  }
})
const clickBtn = (item) => {
  item.show = true
  item.handler()
}
const isInset = (x, y, width, height, mouseX, mouseY) => {
  return (
    x <= mouseX && mouseX <= x + width && y <= mouseY && mouseY <= y + height
  )
}
const canvasMousedown = (event) => {
  console.log(event)
  if (!ctx.value) return
  current = doList.findIndex((item) => {
    return isInset(item.x, item.y, 100, 100, event.offsetX, event.offsetY)
  })
  if (current < 0) return
  const rectX = event.offsetX - doList[current].x
  const rectY = event.offsetY - doList[current].y
  document.onmousemove = function (event) {
    ctx.value?.clearRect(
      0,
      0,
      canvasRef.value?.width || 0,
      canvasRef.value?.height || 0
    )
    doList.forEach((item, index) => {
      if (index != current) item.show && item.handler()
      else item.show && item.handler(event.offsetX - rectX, event.offsetY - rectY)
    })
    doList[current].x = event.offsetX - rectX
    doList[current].y = event.offsetY - rectY
  }
}
const canvasMouseleave = () => {
  document.onmousemove = null
  current = -1
}
const canvasMouseup = () => {
  document.onmousemove = null
  current = -1
}
</script>
<style lang="scss" scoped>
.canvas {
  .btns {
    display: flex;
    column-gap: 10px;
  }
  .my-canvas {
    margin-top: 10px;
    border: 1px solid black;
  }
}
</style>
